import os
import uuid
from datetime import datetime, timedelta
import ntplib
from cryptography.fernet import Fernet
from dotenv import load_dotenv
import time
import sys
import socket

# 加载环境变量
load_dotenv()


# 生成或加载密钥
def generate_or_load_key():
    # 获取当前用户的AppData\Local目录路径
    appdata_path = os.path.expanduser('~')
    # 使用您的主程序名称作为文件夹名称
    app_folder_name = ".yhapp"  # 避免和主程序名字相似
    app_folder_path = os.path.join(appdata_path, app_folder_name)
    # 如果文件夹不存在，则创建它
    if not os.path.exists(app_folder_path):
        os.makedirs(app_folder_path)

    # 定义secret.key的完整路径
    key_path = os.path.join(app_folder_path, 'secret.key')
    if not os.path.exists(key_path):
        key = Fernet.generate_key()
        with open(key_path, "wb") as key_file:
            key_file.write(key)
    else:
        key = open(key_path, "rb").read()
    return key, app_folder_path


# 加密数据
def encrypt(data, key):
    f = Fernet(key)
    encrypted_data = f.encrypt(data.encode())
    return encrypted_data


# 解密数据
def decrypt(data, key):
    f = Fernet(key)
    decrypted_data = f.decrypt(data)
    return decrypted_data.decode()


# 获取硬件ID
def get_hardware_id():
    return hex(uuid.getnode())


# 获取网络时间
def get_network_time(retries=3, timeout=5):
    # client = ntplib.NTPClient()
    # for _ in range(retries):
    #     try:
    #         response = client.request('pool.ntp.org', version=3, timeout=timeout)
    #         return datetime.utcfromtimestamp(response.tx_time)
    #     except ntplib.NTPException:
    #         time.sleep(1)
    #     except socket.gaierror:
    #         continue  # 如果发生地址解析错误，继续尝试直到重试次数用完
    # 如果所有尝试都失败了，使用本地系统时间
    return datetime.now()


# 检查是否过期
def check_expiry():
    # 从generate_or_load_key函数获取密钥和app_folder_path
    key, app_folder_path = generate_or_load_key()

    hardware_id = get_hardware_id()
    expiry_file = os.path.join(app_folder_path, 'expiry.info')

    if not os.path.exists(expiry_file):
        # 第一次运行，生成期限校验文件
        expiry_date = (get_network_time() + timedelta(days=30)).strftime('%Y-%m-%d %H:%M:%S')  # 30天试用期
        data = f"{hardware_id}|{expiry_date}"
        encrypted_data = encrypt(data, key)
        with open(expiry_file, "wb") as file:
            file.write(encrypted_data)
        return {
            'expiry_date': expiry_date,
            'trial_remain': 30
        }
    else:
        # 检查期限
        with open(expiry_file, "rb") as file:
            encrypted_data = file.read()
            data = decrypt(encrypted_data, key)
            saved_hardware_id, expiry_date = data.split('|')
            # if saved_hardware_id != hardware_id:
            #     return {
            #         'expiry_date': expiry_date,
            #         'trial_remain': 0
            #     }
            current_time = get_network_time()
            # if current_time > datetime.strptime(expiry_date, '%Y-%m-%d'):
            #     return False
            delta = datetime.strptime(expiry_date, '%Y-%m-%d %H:%M:%S') - current_time
            delta = max(0, delta.days + 1)
            return {
                'expiry_date': expiry_date,
                'trial_remain': delta
            }


if __name__ == '__main__':
    print(check_expiry())